package com.weimengchao.task.tool;

import com.weimengchao.task.domain.WriteCell;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public class POITool {

    /**
     * 填充单元格数据
     *
     * @param cellContent 单元格内容
     */
    public static void fillCell(WriteCell cellContent) {
        synchronized (cellContent.getSheet()) {
            SXSSFRow row = createRow(cellContent.getSheet(), cellContent.getRowNum());
            SXSSFCell sxssfCell = row.createCell(cellContent.getColumn());
            sxssfCell.setCellStyle(cellContent.getCellStyle());
            if (null != cellContent.getValue()) {
                if (cellContent.getValue() instanceof Integer) {
                    sxssfCell.setCellValue((Integer) cellContent.getValue());
                } else if (cellContent.getValue() instanceof Double) {
                    sxssfCell.setCellValue((Double) cellContent.getValue());
                } else {
                    sxssfCell.setCellValue(cellContent.getValue().toString());
                }
            }
        }
    }

    /**
     * 创建单元格样式
     *
     * @param wb      工作簿
     * @param wrapped true:换行， false:不换行
     * @param format  格式
     */
    public static CellStyle createCellStyle(SXSSFWorkbook wb, boolean wrapped, String format, IndexedColors colors) {
        // 定义单元格格式，添加单元格表样式
        CellStyle cellStyle = wb.createCellStyle();

        //是否换行
        cellStyle.setWrapText(wrapped);

        //颜色
        if (null != colors) {
            cellStyle.setFillForegroundColor(colors.index);
            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        }

        //单元格格式
        if (null != format) {
            DataFormat currencyDataFormat = wb.createDataFormat();
            cellStyle.setDataFormat(currencyDataFormat.getFormat(format));
        }
        return cellStyle;
    }

    /**
     * 创建行
     * 行号存在直接返回，不存在创建对应行
     *
     * @param sheet  表单
     * @param rowNum 行号从0开始
     * @return 行
     */
    public static synchronized SXSSFRow createRow(SXSSFSheet sheet, int rowNum) {
        SXSSFRow row = sheet.getRow(rowNum);
        if (null != row) {
            return row;
        } else {
            return sheet.createRow(rowNum);
        }
    }

    /**
     * 设置下拉框
     *
     * @param workbook    工作簿
     * @param sheet       下拉框所在工作表
     * @param name        名称，不同下拉框数据name不同
     * @param formulaText 公式文本
     * @param firstRow    起始行
     * @param lastRow     结束行
     * @param firstCol    起始列
     * @param lastCol     结束列
     */
    public static void createSelect(SXSSFWorkbook workbook, SXSSFSheet sheet, String name, String formulaText, int firstRow, int lastRow, int firstCol, int lastCol) {
        // 创建名称，可被其他单元格引用
        Name category1Name = workbook.createName();
        category1Name.setNameName(name);
        // 设置名称引用的公式
        category1Name.setRefersToFormula(formulaText);
        // 获取上文名称内数据
        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = helper.createFormulaListConstraint(name);
        // 设置下拉框位置
        CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        DataValidation dataValidation = helper.createValidation(constraint, addressList);
        // 作用在目标sheet上
        sheet.addValidationData(dataValidation);
    }

    /**
     * 创建隐藏sheet
     *
     * @param workbook  工作簿
     * @param sheetName sheet名
     * @param sheetIx   sheet角标
     * @return 隐藏sheet
     */
    public static SXSSFSheet createHiddenSheet(SXSSFWorkbook workbook, String sheetName, int sheetIx) {
        // 创建sheet，写入枚举项
        SXSSFSheet hideSheet = workbook.createSheet(sheetName);

        // 设置hiddenSheet隐藏
        workbook.setSheetHidden(sheetIx, true);
        return hideSheet;
    }

    /**
     * 填充sheet某列值,用于下拉框值填充
     *
     * @param sheet              工作表
     * @param column             所在列
     * @param startRow           开始行号
     * @param explicitListValues 下拉框值
     */
    public static void fill(SXSSFSheet sheet, int column, int startRow, String[] explicitListValues) {
        for (int i = 0; i < explicitListValues.length; i++) {
            sheet.createRow(i + startRow).createCell(column).setCellValue(explicitListValues[i]);
        }
    }

    /**
     * 拼接公式文本
     *
     * @param sheetName 数据所在sheet名称
     * @param column    列  （0-26）
     * @param startRow  开始行
     * @param endRow    结束行
     * @return 公式
     */
    public static String formulaText(String sheetName, int column, int startRow, int endRow) {
        char c = toChar(column);
        return new StringBuilder().append(sheetName).append("!")
            .append("$").append(c).append("$").append(startRow).append(":$").append(c).append("$").append(endRow).toString();
    }

    /**
     * 0-26 转A-Z
     *
     * @param num num
     * @return A-Z
     */
    private static char toChar(int num) {
        if (num < 0 || num > 26) {
            throw new RuntimeException("num范围在0-26之间");
        }
        return (char) (65 + num);
    }

}
